// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie.network;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import zombie.core.Translator;
import zombie.core.network.ByteBufferWriter;
import zombie.core.raknet.UdpConnection;
import zombie.gameStates.GameLoadingState;
import zombie.network.packets.RequestDataPacket;

public class RequestDataManager {
    public static final int smallFileSize = 1024;
    public static final int maxLargeFileSize = 52428800;
    public static final int packSize = 204800;
    private final ArrayList<RequestDataManager.RequestData> requests = new ArrayList();
    private static RequestDataManager instance;

    private RequestDataManager() {
    }

    public static RequestDataManager getInstance() {
        if (instance == null) {
            instance = new RequestDataManager();
        }

        return instance;
    }

    public void ACKWasReceived(RequestDataPacket.RequestID id, UdpConnection connection, int bytesTransmitted) {
        RequestDataManager.RequestData requestData = null;

        for (int _int = 0; _int <= this.requests.size(); _int++) {
            if (((RequestDataManager.RequestData)this.requests.get(_int)).connectionGUID == connection.getConnectedGUID()) {
                requestData = (RequestDataManager.RequestData)this.requests.get(_int);
                break;
            }
        }

        if (requestData != null && requestData.id == id) {
            this.sendData(requestData);
        }
    }

    public void putDataForTransmit(RequestDataPacket.RequestID id, UdpConnection connection, ByteBuffer bb) {
        RequestDataManager.RequestData requestData = new RequestDataManager.RequestData(id, bb, connection.getConnectedGUID());
        this.requests.add(requestData);
        this.sendData(requestData);
    }

    public void disconnect(UdpConnection connection) {
        long _long = System.currentTimeMillis();
        this.requests.removeIf(requestData -> _long - requestData.creationTime > 60000L || requestData.connectionGUID == connection.getConnectedGUID());
    }

    public void clear() {
        this.requests.clear();
    }

    private void sendData(RequestDataManager.RequestData requestData) {
        requestData.creationTime = System.currentTimeMillis();
        int int0 = requestData.bb.limit();
        requestData.realTransmittedFromLastACK = 0;
        UdpConnection udpConnection = GameServer.udpEngine.getActiveConnection(requestData.connectionGUID);
        RequestDataPacket requestDataPacket = new RequestDataPacket();
        requestDataPacket.setPartData(requestData.id, requestData.bb);

        while (requestData.realTransmittedFromLastACK < 204800) {
            int int1 = Math.min(1024, int0 - requestData.realTransmitted);
            if (int1 == 0) {
                break;
            }

            requestDataPacket.setPartDataParameters(requestData.realTransmitted, int1);
            ByteBufferWriter byteBufferWriter = udpConnection.startPacket();
            PacketTypes.PacketType.RequestData.doPacket(byteBufferWriter);
            requestDataPacket.write(byteBufferWriter);
            PacketTypes.PacketType.RequestData.send(udpConnection);
            requestData.realTransmittedFromLastACK += int1;
            requestData.realTransmitted += int1;
        }

        if (requestData.realTransmitted == int0) {
            this.requests.remove(requestData);
        }
    }

    public ByteBuffer receiveClientData(RequestDataPacket.RequestID id, ByteBuffer bb, int fileSize, int bytesTransmitted) {
        RequestDataManager.RequestData requestData = null;

        for (int _int = 0; _int < this.requests.size(); _int++) {
            if (((RequestDataManager.RequestData)this.requests.get(_int)).id == id) {
                requestData = (RequestDataManager.RequestData)this.requests.get(_int);
                break;
            }
        }

        if (requestData == null) {
            requestData = new RequestDataManager.RequestData(id, fileSize, 0L);
            this.requests.add(requestData);
        }

        requestData.bb.position(bytesTransmitted);
        requestData.bb.put(bb.array(), 0, bb.limit());
        requestData.realTransmitted = requestData.realTransmitted + bb.limit();
        requestData.realTransmittedFromLastACK = requestData.realTransmittedFromLastACK + bb.limit();
        if (requestData.realTransmittedFromLastACK >= 204800) {
            requestData.realTransmittedFromLastACK = 0;
            RequestDataPacket requestDataPacket = new RequestDataPacket();
            requestDataPacket.setACK(requestData.id);
            ByteBufferWriter byteBufferWriter = GameClient.connection.startPacket();
            PacketTypes.PacketType.RequestData.doPacket(byteBufferWriter);
            requestDataPacket.write(byteBufferWriter);
            PacketTypes.PacketType.RequestData.send(GameClient.connection);
        }

        GameLoadingState.GameLoadingString = Translator.getText(
            "IGUI_MP_DownloadedLargeFile", requestData.realTransmitted * 100 / fileSize, requestData.id.getDescriptor()
        );
        if (requestData.realTransmitted == fileSize) {
            this.requests.remove(requestData);
            requestData.bb.position(0);
            return requestData.bb;
        } else {
            return null;
        }
    }

    static class RequestData {
        private final RequestDataPacket.RequestID id;
        private final ByteBuffer bb;
        private final long connectionGUID;
        private long creationTime = System.currentTimeMillis();
        private int realTransmitted;
        private int realTransmittedFromLastACK;

        public RequestData(RequestDataPacket.RequestID requestID, ByteBuffer byteBuffer, long _long) {
            this.id = requestID;
            this.bb = ByteBuffer.allocate(byteBuffer.position());
            this.bb.put(byteBuffer.array(), 0, this.bb.limit());
            this.connectionGUID = _long;
            this.realTransmitted = 0;
            this.realTransmittedFromLastACK = 0;
        }

        public RequestData(RequestDataPacket.RequestID requestID, int _int, long _long) {
            this.id = requestID;
            this.bb = ByteBuffer.allocate(_int);
            this.bb.clear();
            this.connectionGUID = _long;
            this.realTransmitted = 0;
            this.realTransmittedFromLastACK = 0;
        }
    }
}
